home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
ab20
/
hardware
/
powerglv.lzh
/
Fingers
/
pwrglove.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-13
|
13KB
|
823 lines
#include "pwrglove.h"
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <hardware/cia.h>
#include <resources/cia.h>
#include <proto/exec.h>
static volatile int times_up;
extern struct CIA ciab;
static struct Library *CIAResource;
static struct Interrupt interrupt;
static UBYTE interrupting;
void closetimer(void);
void
fatal(char *s)
{
printf("fatal error: %s\n", s);
closetimer();
exit(1);
}
void
timerhandler()
{
/* hardware timer interrupt */
times_up = 1;
}
void
timersleep(long ticks)
{
times_up = 0;
ticks -= 8; if (ticks <= 0) { times_up=1; return; } /* yucko */
/* 1.397 usec * n */
ciab.ciatblo = ticks & 0xff;
ciab.ciatbhi = (ticks>>8) & 0xff;
/* one-shot */
ciab.ciacrb |= CIACRBF_RUNMODE | CIACRBF_LOAD | CIACRBF_START;
while (!times_up) {}
}
void
opentimer()
{
static char* timername = "glove.timer";
/* install interrupt handler */
CIAResource = OpenResource(CIABNAME);
if (CIAResource == NULL) fatal("can't get timer resource");
interrupt.is_Node.ln_Type = NT_INTERRUPT;
interrupt.is_Node.ln_Pri = 127;
interrupt.is_Node.ln_Name = timername;
interrupt.is_Data = NULL;
interrupt.is_Code = timerhandler;
if (AddICRVector(CIAResource, CIAICRB_TB, &interrupt) != NULL) {
fatal("can't use CIA B Timer B");
}
/* this timer is all mine */
interrupting = 1;
SetICR(CIAResource, CIAICRF_TB);
AbleICR(CIAResource, CIAICRF_SETCLR | CIAICRF_TB);
times_up = 0;
}
void
closetimer()
{
if (interrupting) {
ciab.ciacrb &= ~CIACRBF_START;
AbleICR(CIAResource, CIAICRF_TB);
RemICRVector(CIAResource, CIAICRB_TB, &interrupt);
interrupting = 0;
}
}
extern struct CIA far ciaa;
/* bits from parallel port -- Alan's hack */
#define GDATA 0x04 /* glove data in */
#define GLATCH 0x02 /* glove latch out */
#define GCLOCK 0x01 /* glove clock out */
#define GCLOLAT (GLATCH|GCLOCK) /* latch and clock */
#define getbit() (ciaa.ciaprb & GDATA) >> 2
#define initport() ciaa.ciaddrb = GCLOLAT
/* delays in microseconds */
#define D2BYTES 96
#define D2BITS 22
#define D2SLOW 14720
#define C0L0() ciaa.ciaprb = 0 /* clock 0 latch 0 */
#define C0L1() ciaa.ciaprb = GLATCH /* clock 0 latch 1 */
#define C1L0() ciaa.ciaprb = GCLOCK /* clock 1 latch 0 */
#define C1L1() ciaa.ciaprb = GCLOLAT /* clock 1 latch 1 */
#define setporta() delay(3)
#define setportb() delay(3)
unsigned char getbyte (void);
/* convert microseconds to cia ticks */
#define delay(usec) timersleep((usec*1397)/1000)
int control_c()
{
closetimer();
printf("<<goodbye>>\n");
return 1; /* causes exit */
}
void query_glove(glove_data *g)
{
unsigned char buf[12];
register char *bp;
/* read 12 byte packet */
bp = buf;
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2BYTES);
*bp++ = getbyte ();
delay (D2SLOW);
*bp++ = getbyte ();
delay (D2SLOW);
*bp++ = getbyte ();
delay (D2SLOW);
*bp++ = getbyte ();
delay (D2SLOW);
*bp++ = getbyte ();
delay (D2SLOW);
/* Glove packet isn't quite as described above */
/* Let's see if we can figure it out */
{
int i,k,n;
/* look for FF FF A0 */
/* almost always starts at offset 7 so look there first */
n = -1;
for (k=0,i=7; k<12; ++k,++i) {
if (buf[i%12] == (unsigned char)0xff &&
buf[(i+1)%12] == (unsigned char)0xff &&
buf[(i+2)%12] == (unsigned char)0xa0) {
/* yah! */
n = (i+3)%12;
g->x = buf[n];
g->y = buf[(n+1)%12];
g->z = buf[(n+2)%12];
g->rot = buf[(n+3)%12];
g->fingers = buf[(n+4)%12];
g->keys = buf[(n+5)%12];
g->dum0 = 0xa0;
g->dum7 = buf[(n+6)%12];
g->dum8 = buf[(n+7)%12];
g->dum9 = buf[(n+8)%12];
g->dumA = 0xff;
g->dumB = 0xff;
return;
}
}
/* no valid data found */
}
}
unsigned char getbyte ()
{
register unsigned Glov = 0;
/* prepare port b as output port */
setportb ();
/* generate a reset (latch) pulse */
C1L0 ();
C1L1 ();
delay(5); /* 5 us delay */
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
return (unsigned char) Glov; /* return the byte */
}
void init_glove()
{
register unsigned char Glov = 0;
opentimer();
onbreak(control_c);
/* initialize hardware interface */
initport();
/* read 4 bits from glove */
setportb ();
/* generate a reset (latch) pulse */
C1L0 ();
C1L1 ();
delay(5); /* 5 us delay */
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* configure port a as input */
setporta ();
/* read a bit */
Glov <<= 1;
Glov |= getbit();
/* prepare port b as output port */
setportb ();
/* generate a clock pulse */
C0L0 ();
C1L0 ();
/* end of read 4 bits */
/* prepare port b as output port */
setportb ();
C1L0 ();
delay(7212);
/* delay (16950); /* 7212 us delay */
setportb ();
C1L1 ();
delay(2260);
/* delay (4750); /* 2260 us delay */
/* prepare port b as output port */
setportb ();
C1L0 (); /* Start of 1. Byte */
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L1 ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L0 ();
C0L0 ();
C1L0 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C1L1 (); /* Start of 2. Byte */
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L0 ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L1 ();
C0L1 ();
C1L1 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C1L0 (); /* Start of 3. Byte */
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L1 ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L0 ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C0L0 (); /* start of 4. byte */
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C0L0 (); /* start of 5. byte */
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L1 ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L0 ();
C0L0 ();
C1L0 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C1L1 (); /* start of 6. byte */
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L1 ();
C1L1 ();
delay (D2BYTES);
/* prepare port b as output port */
setportb ();
C1L0 (); /* start of 7. byte */
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C0L0 ();
C1L0 ();
delay (D2BITS);
/* prepare port b as output port */
setportb ();
C1L1 ();
C0L1 ();
C1L1 ();
delay(892);
/* delay (1090); /* 892 us delay (end of 7. byte) */
/* prepare port b as output port */
setportb ();
C1L0 ();
delay(50000);
/* delay (60000); /* some time for the glove controller
to relax */
}